package cn.simon.free.logtrack.utils;

import cn.simon.free.logtrack.enums.LogTrackEnum;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 日志追踪
 *
 * @author simon
 * @date 2021/04/17 13:42
 * @copyright:
 * @modifier
 * @motto a no talent, people who have to study hard
 */
public class LogTrackUtils {

    private static final Map<String, LinkedList<String>> ctx = Collections.synchronizedMap(Maps.newLinkedHashMap());
    private static final ThreadLocal<Map<String, String>> threadLocal = new ThreadLocal<>();

    public static void init(Map<String, String> maps) {
        if (null == threadLocal.get()) {
            threadLocal.set(maps);
            String trackId = maps.get(LogTrackEnum.LOG_TRACK_MARK.getValue());
            String trackName = maps.get(LogTrackEnum.LOG_TRACK_NAME.getValue());
            LinkedList<String> logTrackLinkedList = Lists.newLinkedList();
            logTrackLinkedList.addFirst(trackName);
            ctx.put(trackId, logTrackLinkedList);
        }
    }

    public static List<String> get() {
        Map<String, String> maps = threadLocal.get();
        if (Objects.nonNull(maps) && !maps.isEmpty()) {
            return ctx.get(maps.get(LogTrackEnum.LOG_TRACK_MARK.getValue()));
        }
        return null;
    }

    public static String get2String() {
        return get().stream().collect(Collectors.joining("\r\n"));
    }

    public static boolean add(String value) {
        Map<String, String> maps = threadLocal.get();
        if (Objects.nonNull(maps) && !maps.isEmpty()) {
            String trackId = maps.get(LogTrackEnum.LOG_TRACK_MARK.getValue());
            return add(trackId, value);
        }
        return false;
    }

    private static boolean add(String trackId, String value) {
        if (!Strings.isNullOrEmpty(trackId)) {
            LinkedList<String> logTrackLinkedList = Optional.ofNullable(ctx.get(trackId)).orElse(Lists.newLinkedList());
            logTrackLinkedList.add(value);
            ctx.put(trackId, logTrackLinkedList);
            return true;
        }
        return false;
    }

    public static void remove() {
        Map<String, String> maps = threadLocal.get();
        if (Objects.nonNull(maps) && !maps.isEmpty()) {
            String trackId = maps.get(LogTrackEnum.LOG_TRACK_MARK.getValue());
            ctx.remove(trackId);
            threadLocal.remove();
        }
    }
}
